home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / bin / foomatic-ppd-to-xml < prev    next >
Encoding:
Text File  |  2010-09-16  |  8.8 KB  |  261 lines

  1. #!/usr/bin/perl
  2. # -*- perl -*-
  3.  
  4. # Foomatic printer XML file generator to get XML files corresponding
  5. # to manufacturer-supplied PostScript PPDs (or also PPDs from driver
  6. # packages).
  7.  
  8. use Foomatic::Defaults;
  9. use Foomatic::DB;
  10. use Getopt::Std;
  11. use Data::Dumper;
  12. #use strict;
  13.  
  14. my $debug = 0;
  15.  
  16. # Program name
  17. $0 =~ m!/([^/]+)\s*$!;
  18. my $progname = ($1 || $0);
  19.  
  20. help() if !@ARGV;
  21. #my ($opt_h, $opt_d, $opt_p, $opt_A, $opt_P, $opt_w);
  22. getopts("d:r:p:lb:f:nxh");
  23. help() if $opt_h;
  24. my $drivers = $opt_d;
  25. my $rdriver = $opt_r;
  26. my $pdls = $opt_p;
  27. my $ppdlink = $opt_l;
  28. my $basedir = $opt_b;
  29. my $destdir = $opt_f;
  30. my $nomod = $opt_n;
  31. my $nocheck = $opt_x;
  32.  
  33. $ppdfile = $ARGV[0];
  34.  
  35. if ($ppdlink && !$drivers) {
  36.     $ppdlink = 0;
  37.     warn("WARNING: \"-l\" set without supplying a driver via \"-d\". No PPD file links will get created!\n");
  38. }
  39.  
  40. my $ppddlpath;
  41. if ($basedir) {
  42.     $basedir =~ s:/+$::;
  43.     if (! -d $basedir) {
  44.     die ("PPD base directory $basedir does not exist!\n");
  45.     }
  46.     if (! -r $ppdfile) {
  47.     $ppddlpath = $ppdfile;
  48.     $ppdfile = $basedir . "/" . $ppdfile;
  49.     if (! -r $ppdfile) {
  50.         die ("Given PPD file not found, neither as $ppddlpath nor as $ppdfile!\n");
  51.     }
  52.     } else {
  53.     $ppddlpath = $1 if $ppdfile =~ m:$basedir/(.*)$:;
  54.     }
  55. } else {
  56.     if (! -r $ppdfile) {
  57.     die ("Given PPD file $ppdfile not found!\n");
  58.     }
  59.     $ppddlpath = $ppdfile;
  60. }
  61.  
  62. my $parameters = {
  63.     ($drivers ? ('drivers' => [split(',', $drivers)]) : ()),
  64.     ($rdriver ? ('recommendeddriver' => $rdriver) : ()),
  65.     ($pdls ? ('pdls' => [split(',', $pdls)]) : ()),
  66.     ($ppdlink ? ('ppdlink' => 1) : ()),
  67.     ($basedir ? ('basedir' => $basedir) : ()),
  68. };
  69.  
  70. my $db = Foomatic::DB->new();
  71. my $dat = ppdtoperl($ppdfile, $parameters);
  72. if ($ppddlpath eq "") {
  73.     $mk = $dat->{'id'};
  74.     $mk =~ s/^([^\-]+)\-.*$/$1/;
  75.     $ppd = $ppdfile;
  76.     $ppd =~ s:^.*/([^/]+):$1:;
  77.     $pdddlpath = "PPD/$mk/$ppd";    
  78. }
  79. $ppddlpath =~ s/\.gz$//i;
  80. my @existing = ();
  81. if (!$nocheck) {
  82.     @existing = $db->find_printer("$dat->{'make'}|$dat->{'model'}", 4, 1);
  83.     foreach my $product (@{$dat->{ppdproduct}}) {
  84.     my @pids = $db->find_printer("$dat->{'make'}|$product", 4, 1);
  85.     push(@existing,
  86.          grep {
  87.          !Foomatic::DB::member($_, @existing);
  88.          } @pids);
  89.     }
  90.     push(@existing,
  91.      grep {
  92.          !Foomatic::DB::member($_, @existing);
  93.      } map {
  94.        m:^(.*)\.xml$:; $1;
  95.      } map {
  96.        m:([^/]+)$:; $1;
  97.      } split(/\n/s, 
  98.          `find $libdir/db/source/printer -name "*.xml" -print0 | xargs -0 grep -l $ppddlpath`));
  99. }
  100. my $entryfound = 0;
  101. foreach my $entry (@existing) {
  102.     my $d = $db->get_printer($entry);
  103.     my $result;
  104.     next if $d->{'noxmlentry'};
  105.     $entryfound = 1;
  106.     last if $nomod;
  107.     $db->{'dat'} = $d;
  108.     if (!defined($parameters->{'drivers'})) {
  109.     $parameters->{'drivers'} = [$dat->{'driver'}];
  110.     }
  111.     if (!defined($parameters->{'pdls'})) {
  112.     $parameters->{'pdls'} = [split(',', $dat->{'general_cmd'})];
  113.     } else {
  114.     push(@{$parameters->{'pdls'}}, split(',', $dat->{'general_cmd'}));
  115.     }
  116.     Foomatic::DB::apply_driver_and_pdl_info($db->{'dat'}, $parameters);
  117.     $db->{'dat'}{'general_ieee'} = $dat->{'general_ieee'} if
  118.     defined($dat->{'general_ieee'}) && 
  119.     !defined($db->{'dat'}{'general_ieee'});
  120.     $db->{'dat'}{'general_mfg'} = $dat->{'general_mfg'} if
  121.     defined($dat->{'general_mfg'}) &&
  122.     !defined($db->{'dat'}{'general_mfg'});
  123.     $db->{'dat'}{'general_mdl'} = $dat->{'general_mdl'} if
  124.     defined($dat->{'general_mdl'}) &&
  125.     !defined($db->{'dat'}{'general_mdl'});
  126.     $db->{'dat'}{'general_des'} = $dat->{'general_des'} if
  127.     defined($dat->{'general_des'}) &&
  128.     !defined($db->{'dat'}{'general_des'});
  129.     $db->{'dat'}{'general_cmd'} = $dat->{'general_cmd'} if
  130.     defined($dat->{'general_cmd'}) &&
  131.     !defined($db->{'dat'}{'general_cmd'});
  132.     $db->{'dat'}{'comment'} .= "\n      <p>\n\n" . $dat->{'comment'};
  133.     my $xml1 = $db->perltoxml('p');
  134.     my $xml2 = $db->get_printer_xml($entry);
  135.     $xml2 =~ s/(<\/functionality>)/$1\n  <driver><\/driver>/s if 
  136.     $xml2 !~ /<driver>/;
  137.     $xml2 = transferregexp($xml1, $xml2,
  138.     '<driver>\S*<\/driver>');
  139.     $xml2 =~ s/(<\/driver>)/$1\n  <drivers>\n  <\/drivers>/s if 
  140.     $xml2 !~ /<drivers>/;
  141.     $xml2 = transferregexp($xml1, $xml2,
  142.     '<drivers>.*<\/drivers>');
  143.     $xml2 =~ s/(<\/(mechanism|url)>)/$1\n  <lang>\n  <\/lang>/s if 
  144.     $xml2 !~ /<lang>/;
  145.     $xml2 = transferregexp($xml1, $xml2,
  146.     '<lang>.*<\/lang>');
  147.     $xml2 =~ s/(<\/lang>)/$1\n  <autodetect>\n  <\/autodetect>/s if 
  148.     $xml2 !~ /<autodetect>/;
  149.     $xml2 =~ s/(<autodetect>)/$1\n    <general>\n    <\/general>/s if 
  150.     $xml2 !~ /<autodetect>[\s\n\r]*<general>/s;
  151.     $xml2 = transferregexp($xml1, $xml2,
  152.     '<autodetect>[\s\n\r]*<general>.*<\/general>');
  153.     $xml2 = transferregexp($xml1, $xml2,
  154.     '<\/drivers>[\s\n\r]*<comments>.*<\/comments>[\s\n\r]*<\/printer>');
  155.     $result = $xml2;
  156.     print "Modifying printer entry $db->{'dat'}{'id'}.xml ...\n";
  157.     open FILE, "> " . ($destdir ? $destdir . "/" : ()) . 
  158.     $db->{'dat'}{'id'} . ".xml" or
  159.     die "Cannot write file $db->{'dat'}{'id'}.xml!\n";
  160.     print FILE $result;
  161.     close FILE;
  162.     delete($db->{'dat'});
  163. }
  164. if (!$entryfound) {
  165.     $db->{'dat'} = $dat;
  166.     $db->{'dat'}{'comment'} =
  167.     "      This database entry was automatically generated\n" .
  168.     "      from the PPD file for this printer.<p>\n\n" .
  169.     $db->{'dat'}{'comment'};
  170.     $db->{'dat'}{'functionality'} = "A";
  171.     foreach my $product (@{$db->{'dat'}{ppdproduct}}) {
  172.     $db->{'dat'}{'model'} =
  173.         Foomatic::DB::clean_manufacturer_name(Foomatic::DB::clean_model_name($product))
  174.         if scalar(@{$db->{'dat'}{ppdproduct}}) > 1;
  175.     $db->{'dat'}{'model'} =~ s/^$db->{'dat'}{'make'}\s*//i;
  176.     $db->{'dat'}{'id'} =
  177.         Foomatic::DB::generatepid($db->{'dat'}{'make'},
  178.                       $db->{'dat'}{'model'});
  179.     if (scalar(@{$db->{'dat'}{ppdproduct}}) > 1) {
  180.         $db->{'dat'}{'general_mfg'} = $db->{'dat'}{'ppdmanufacturer'} if
  181.         $db->{'dat'}{'ppdmanufacturer'} &&
  182.         !$db->{'dat'}{'general_mfg'};
  183.         $db->{'dat'}{'general_mdl'} = $product;
  184.         $db->{'dat'}{'general_ieee'} = "MFG:" .
  185.         $db->{'dat'}{'general_mfg'} .
  186.         ";MDL:" . $db->{'dat'}{'general_mdl'} . ";" .
  187.         ($db->{'dat'}{'general_cmd'} ?
  188.          "CMD:" . $db->{'dat'}{'general_cmd'} . ";" : "");
  189.     }
  190.     $result = $db->perltoxml('p');
  191.     print "Creating new printer entry $db->{'dat'}{'id'}.xml ...\n";
  192.     open FILE, "> " . ($destdir ? $destdir . "/" : ()) . 
  193.         $db->{'dat'}{'id'} . ".xml" or
  194.         die "Cannot write file $db->{'dat'}{'id'}.xml!\n";
  195.     print FILE $result;
  196.     close FILE;
  197.     }
  198.     delete($db->{'dat'});
  199. }
  200.  
  201. exit 0;
  202.  
  203. sub transferregexp {
  204.  
  205.     my ($src, $dest, $regexp) = @_;
  206.  
  207.     # This function copies the text fraction matching $regexp out of
  208.     # the first string, cuts the piece of the second matching $regexp
  209.     # out of the second string and replaces it by the piece copied
  210.     # from the first string. This is mainly for transfering XML
  211.     # sections from one XML file to another (strings can be
  212.     # multi-line) without needing to rewrite the unaffected parts of
  213.     # the XML file.
  214.  
  215.     $src =~ m/($regexp)/s;
  216.     my $totransfer = $1;
  217.     $dest =~ s/$regexp/$totransfer/s if $totransfer;
  218.     return $dest;
  219. }
  220.  
  221. sub help {
  222.     print <<HELP;
  223.  
  224. $progname <options> <ppdfile>
  225. $progname -h
  226.  
  227.  <ppdfile>      : PPD file for which a printer XML file should be created
  228.  -d <drivers>   : Comma-separated list of drivers with which the printer
  229.                   works. First driver is the one for which the PPD file is.
  230.                   If not otherwise stated by the "-r" option, this is also
  231.                   the recommended driver.
  232.  -r <driver>    : Recommended driver. Supply this option to specify another
  233.                   driver than the driver from the PPD/the first one from the
  234.                   "-d" argument as the recommended driver.
  235.  -p <pdls>      : Comma-separated list of known Page Description Languages
  236.                   (PDLs) which the printer supports. This will add all 
  237.                   suitable drivers to the XML entry. Currently supported are:
  238.                   Postscript, PCLXL, PCL6, PCL5e, PCL5c, PCL5, and PCL4.
  239.  -l             : Add a link to the PPD file to the driver entry in the
  240.                   XML file.
  241.  -b <directory> : Base directory for a relative link to the PPD. If the
  242.                   base directory is given, the link set via the -l option 
  243.                   is relative to this directory (and not relative to the
  244.                   current directory). With a base directory given the 
  245.                   <ppdfile> can also be given relative to this directory.
  246.  -f <directory> : Directory where the resulting XML file to write to. The
  247.                   name of the file will be the printer ID with the ".xml"
  248.                   extension.
  249.  -n             : Do not write modified versions of existing XML files,
  250.                   only create XML files for printers for which there is no
  251.                   XML file yet.
  252.  -x             : Create XML files independent of whether there are already
  253.                   XML files for the printers covered by the PPD or not.
  254.  -h             : show help information
  255.  
  256.  
  257. HELP
  258.     exit 1;
  259.  
  260. }
  261.